package com.sun.lib_tag;
/*
 *
 * #                                                   #
 * #                       _oo0oo_                     #
 * #                      o8888888o                    #
 * #                      88" . "88                    #
 * #                      (| -_- |)                    #
 * #                      0\  =  /0                    #
 * #                    ___/`---'\___                  #
 * #                  .' \\|     |# '.                 #
 * #                 / \\|||  :  |||# \                #
 * #                / _||||| -:- |||||- \              #
 * #               |   | \\\  -  #/ |   |              #
 * #               | \_|  ''\---/''  |_/ |             #
 * #               \  .-\__  '-'  ___/-. /             #
 * #             ___'. .'  /--.--\  `. .'___           #
 * #          ."" '<  `.___\_<|>_/___.' >' "".         #
 * #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #
 * #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #
 * #     =====`-.____`.___ \_____/___.-`___.-'=====    #
 * #                       `=---='                     #
 * #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #
 * #                                                   #
 * #               佛祖保佑         永无BUG              #
 * #                                                   #
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by ESSC07 on 2021/12/14.
 */
public class TagFlowLayout extends TagFlowGroup implements TagAdapter.OnDataChangedListener {
    private TagAdapter adapter;
    private OnTagClickListener onTagClickListener;
    private OnTagSelectListener onTagSelectListener;
    private int maxSelect;
    private boolean singleSelect = false;

    public interface OnTagClickListener {
        void onTagClick(TagView view, int position, TagFlowLayout parent);
    }

    public interface OnTagSelectListener {
        void onSelected(Set<Integer> selectPos);
    }

    public void setOnTagClickListener(OnTagClickListener onTagClickListener) {
        this.onTagClickListener = onTagClickListener;
    }

    public void setOnTagSelectListener(OnTagSelectListener onTagSelectListener) {
        this.onTagSelectListener = onTagSelectListener;
    }

    public TagFlowLayout(Context context) {
        this(context, null);
    }

    public TagFlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TagFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TagFlowLayout);
        maxSelect = array.getInt(R.styleable.TagFlowLayout_tf_maxSelect, 0);
        singleSelect = array.getBoolean(R.styleable.TagFlowLayout_tf_singleSelect, false);
        if (singleSelect) maxSelect = 0;
        array.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void setAdapter(TagAdapter adapter) {
        this.adapter = adapter;
        this.adapter.setOnDataChangedListener(this);
        notifyAdapter();
    }

    public void setMaxSelect(int maxSelect) {
        this.maxSelect = maxSelect;
        notifyAdapter();
    }

    @Override
    protected void notifyAdapter() {
        if (adapter == null)
            throw new RuntimeException("adpater is null");
        removeAllViews();
        TagView tagContainer;
        for (int i = 0; i < adapter.getItemCount(); i++) {
            View tagView = adapter.getView(this, i, adapter.getItem(i));
            tagContainer = new TagView(getContext());
            tagView.setDuplicateParentStateEnabled(true);
            if (tagView.getLayoutParams() != null) {
                tagContainer.setLayoutParams(tagView.getLayoutParams());
            } else {
                MarginLayoutParams params = new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                tagContainer.setLayoutParams(params);
            }
            LayoutParams params = new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            tagView.setLayoutParams(params);
            tagContainer.addView(tagView);
            addView(tagContainer);
            tagView.setClickable(false);
            if (adapter.getCheckedList().contains(i)) {
                setChildChecked(i, tagContainer);
            }
            final TagView finalTagContainer = tagContainer;
            final int finalI = i;
            tagView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    doChildSelect(finalTagContainer, finalI);
                    if (onTagClickListener != null)
                        onTagClickListener.onTagClick(finalTagContainer, finalI, TagFlowLayout.this);
                }
            });
        }
    }

    private void refreshAdapterStatusChanged(){
        for(int i=0;i<getChildCount();i++){
           // View tagView = adapter.getView(this,i,adapter.getItem(i));
            TagView tagView = (TagView) getChildAt(i);
            if(adapter.getCheckedList().contains(i)) {
                setChildChecked(i,tagView);
            }else{
                setChildUnChecked(i,tagView);
            }
        }
    }

    private void doChildSelect(TagView view, int position) {
        if (singleSelect) {
            adapter.singleSelect(position);
           // notifyAdapter();
            refreshAdapterStatusChanged();
        } else {
            HashSet hashSet = adapter.getCheckedList();
            if (!view.isChecked()) {
                if (hashSet.size() >= maxSelect) return;
                setChildChecked(position, view);
            } else {
                setChildUnChecked(position, view);
            }
        }
        notifyOnSelectListener();
    }

    public void selectTag(int position) {
        if (position < getChildCount()) {
            TagView tagView = (TagView) getChildAt(position);
            HashSet hashSet = adapter.getCheckedList();
            if (hashSet.contains(position) || hashSet.size() >= maxSelect) return;
            setChildChecked(position, tagView);
            notifyOnSelectListener();
        }
    }

    public void unSelectTag(int position) {
        if (position < getChildCount()) {
            TagView tagView = (TagView) getChildAt(position);
            setChildChecked(position, tagView);
            notifyOnSelectListener();
        }
    }

    private void notifyOnSelectListener() {
        if (onTagSelectListener != null)
            onTagSelectListener.onSelected(new HashSet<Integer>(adapter.getCheckedList()));
    }

    @Override
    public void onDataChanged() {
        notifyAdapter();
    }

    private void setChildChecked(int position, TagView view) {
        if (adapter == null) return;
        view.setSelected(true);
        view.setChecked(true);
        adapter.onSelected(position, view);
    }

    private void setChildUnChecked(int position, TagView view) {
        view.setSelected(false);
        view.setChecked(false);
        adapter.onUnSelected(position, view);
    }

    public Set<Integer> getSelectList() {
        return new HashSet<>(adapter.getCheckedList());
    }

    public TagAdapter getAdapter() {
        return adapter;
    }

    @Nullable
    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable("key_def", super.onSaveInstanceState());
        StringBuilder builder = new StringBuilder();
        HashSet<Integer> list = adapter.getCheckedList();
        if (!list.isEmpty()) {
            for (Integer pos : list) {
                builder.append(pos + "&");
            }
            String selectPos = builder.substring(0, builder.length() - 1);
            bundle.putString("key_select_pos", selectPos);
        }
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            String selectPos = bundle.getString("key_select_pos");
            if (!TextUtils.isEmpty(selectPos)) {
                List<Integer> list = new ArrayList<>();
                String[] split = selectPos.split("&");
                for (String str : split) {
                    int i = Integer.parseInt(str);
                    TagView tagView = (TagView) getChildAt(i);
                    if (tagView != null) setChildChecked(i, tagView);
                }

            } else {
                super.onRestoreInstanceState(bundle.getParcelable("key_def"));
            }
        } else {
            super.onRestoreInstanceState(state);
        }


    }
}
